It’s best to avoid giving default argument initializers to virtual functions. While doing so is legal, the code is unlikely to be correctly
maintained over time and will lead to incorrect polymorphic code and unnecessary complexity in a class hierarchy.
Noncompliant code example
class Base {
public:
virtual void fun(int p = 42) { // Noncompliant
// ...
}
};
class Derived : public Base {
public:
void fun(int p = 13) override { // Noncompliant
// ...
}
};
class Derived2 : public Base {
public:
void fun(int p) override {
// ...
}
};
int main() {
Derived *d = new Derived;
Base *b = d;
b->fun(); // uses default argument 42
d->fun(); // uses default argument 13; was that expected?
Base *b2 = new Base;
Derived2 *d2 = new Derived2;
b2->fun(); // uses default argument 42
d2->fun(); // compile time error; was that expected?
}
Compliant solution
class Base {
public:
void fun(int p = 42) { // non-virtual forwarding function
fun_impl(p);
}
protected:
virtual void fun_impl(int p) {
// ...
}
};
class Derived : public Base {
protected:
void fun_impl(int p) override {
// ...
}
};
class Derived2 : public Base {
protected:
void fun_impl(int p) override {
// ...
}
};